package com.easylinkin.linkappapi.alarm.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.easylinkin.linkappapi.alarm.constant.AlarmConstant.ProcessStatus;
import com.easylinkin.linkappapi.alarm.entity.Alarm;
import com.easylinkin.linkappapi.alarm.entity.AlarmProcess;
import com.easylinkin.linkappapi.alarm.mapper.AlarmProcessMapper;
import com.easylinkin.linkappapi.alarm.service.AlarmProcessService;
import com.easylinkin.linkappapi.alarm.service.AlarmService;
import com.easylinkin.linkappapi.common.exceptions.BusinessException;
import com.easylinkin.linkappapi.common.service.CommonService;
import com.easylinkin.linkappapi.device.constant.DeviceConstant.DeviceStatusEnum;
import com.easylinkin.linkappapi.device.entity.Device;
import com.easylinkin.linkappapi.device.service.DeviceService;
import com.easylinkin.linkappapi.listener.AirMonitorListener;
import com.easylinkin.linkappapi.listener.DeviceMonitorListener;
import java.util.Date;
import java.util.List;
import javax.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;

/**
 * <p>
 * 告警处理服务实现类
 * </p>
 *
 * @author TongJie
 * @since 2020-04-27
 */
@Service
public class AlarmProcessServiceImpl extends ServiceImpl<AlarmProcessMapper, AlarmProcess> implements AlarmProcessService {

    @Resource
    private CommonService commonService;

    @Resource
    private AlarmService alarmService;
    @Resource
    private DeviceService deviceService;
    @Resource
    AirMonitorListener airMonitorListener;
    @Resource
    private DeviceMonitorListener deviceMonitorListener;

    private static final Logger LOGGER = LoggerFactory.getLogger(AlarmProcessServiceImpl.class);

    @Override
    public void add(AlarmProcess alarmProcess) {
        LOGGER.info("新增告警处理");
        Assert.notNull(alarmProcess, "参数为空");
        Assert.notNull(alarmProcess.getAlarmId(), "参数告警id为空");

        Alarm alarm = alarmService.getById(alarmProcess.getAlarmId());
        Assert.notNull(alarm, "查得告警为空");
        if (alarm.getStatus() != null && alarm.getStatus().equals(ProcessStatus.PROCESSED.getType())) {
            throw new BusinessException("告警已被处理");
        }
        validParamRequired(alarmProcess);
        validParamFormat(alarmProcess);
        commonService.setCreateAndModifyInfo(alarmProcess);
        alarmProcess.setHandlerId(alarmProcess.getCreator());
        alarmProcess.setProcessTime(new Date());
        alarmProcess.setStatus(ProcessStatus.PROCESSED.getType());

        //设置为已处理
        alarm.setStatus(ProcessStatus.PROCESSED.getType());
        alarmService.updateById(alarm);
        LOGGER.info("更新告警工单:{}", JSONObject.toJSONString(alarm));
        save(alarmProcess);
        LOGGER.info("新增告警处理:{}", JSONObject.toJSONString(alarmProcess));
        if (ObjectUtils.isEmpty(alarm.getDeviceCode())) {
            return;
        }
        Device device = deviceService.findOneByDeviceCode(alarm.getDeviceCode());
        if (ObjectUtils.isEmpty(device)) {
            return;
        }
//        根据设备编号查询 该设备是否存在未处理的告警
        int count = alarmService.countAlarmByDeviceCodeAndStatus(alarm.getDeviceCode(), ProcessStatus.NOT_PROCESSED.getType());
        if (count == 0) {
            device.setStatus(DeviceStatusEnum.NORMAL.getType());
            deviceService.update(device);
        }
//        TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
//            @Override
//            public void afterCommit() {
                sendDeviceMessage(alarm.getDeviceCode());
//            }
//        });
    }


    private void sendDeviceMessage(String device_id){
        //2021-07-23修改，避免被规则引擎给终止，推送设备数据
        Device oneByDeviceCode = deviceService.findOneByDeviceCode(device_id);
        //ws设备数据推送
        airMonitorListener.sendNotice(oneByDeviceCode);
//        deviceAttributeStatusListener.sendNotice(oneByDeviceCode);
        deviceMonitorListener.sendNotice(oneByDeviceCode);
    }

    @Override
    public void addBatch(String processResult, Integer mistakeFlag, List<AlarmProcess> alarmProcessList) {
        Assert.notNull(mistakeFlag, "是否误报参数为空");
        Assert.notEmpty(alarmProcessList, "alarmProcessList 参数为空");
        for (AlarmProcess alarmProcess : alarmProcessList) {
            alarmProcess.setMistakeFlag(mistakeFlag);
            alarmProcess.setProcessResult(processResult);
            add(alarmProcess);
        }
    }


    /**
     * 校验参数必填
     */
    private void validParamRequired(AlarmProcess alarmProcess) {
        Assert.notNull(alarmProcess, "参数为空");
        Assert.isTrue(StringUtils.isNotBlank(alarmProcess.getAlarmId()), "告警id为空");
        Assert.isTrue(StringUtils.isNotBlank(alarmProcess.getDeviceCode()), "设备编号为空");
        Assert.notNull(alarmProcess.getMistakeFlag(), "参数是否误报为空");
    }

    /**
     * 校验参数格式
     */
    private void validParamFormat(AlarmProcess alarmProcess) {
        Assert.isTrue(alarmProcess.getDescription() == null || alarmProcess.getDescription().length() <= 255, "描述超长");
        Assert.isTrue(alarmProcess.getProcessResult() == null || alarmProcess.getProcessResult().length() <= 512, "处理结果超长");
    }

    @Override
    public List<AlarmProcess> getAlarmProcesses(AlarmProcess alarmProcess) {
        return null;
    }

    @Override
    public IPage<AlarmProcess> getAlarmProcessPage(Page page, AlarmProcess customQueryParams) {
        return null;
    }

    @Override
    public AlarmProcess getAlarmProcess(String alarmId) {
        AlarmProcess entity = new AlarmProcess();
        entity.setAlarmId(alarmId);
        QueryWrapper<AlarmProcess> queryWrapper = new QueryWrapper<>(entity);
        queryWrapper.eq("alarm_id", alarmId);
        return baseMapper.selectOne(queryWrapper);
    }

    @Override
    public boolean deleteBatch(List<AlarmProcess> alarmProcessList) {
        return false;
    }
}
